/* global $, visoConfig, Mustache, uuid, jsPlumb */

(function () {
    //基本变量
    var node_num = 0;//序号
    var flowNo = $("#control_body_form1").find("input[name='sysAuditRule.auditType']").val();
    var nodeCode_prefix=strUtil.doNull(flowNo,"Node");//节点编号前缀
    var click_jnodeBoxObj = null;//当前选中节点box
    var click_connectionObj = null;//当前选中连线对象
    var checkedNodeMap = {};//已选择节点对应个数
    var areaId = "diagramContainer-main";//设计区域
    var jnode_controlId="#diagramContainer-control";//参数设置区域
    var jnode_areaId = '#'+areaId;//设计区域
    var jnode_templateId = "#jnode-template";//节点模板
    var enable_connect_server = true;//true/false 是否开启读后台服务请求数据
    var enable_console = true;

    //设置右侧【参数设置】组件可拖动
    // $("#diagramContainer-tools-box").draggable({containment: ".content-wrapper"}).resizable({containment: ".content-wrapper",minWidth: 150});
    //设计区域屏蔽右键功能
    $(jnode_areaId).bind("contextmenu", function (e) {
        // $(jnode_areaId).find(".jnode-panel").removeClass("jnode-panel-active");//右键取消选中样式
        return false;
    });

    //定义节点样式
    var jnodeClassMap = {};
    $("#diagramContainer-left").find("div[data-jnode-type]").each(function () {
        jnodeClassMap[$(this).attr("data-jnode-type")] = $(this).attr("data-jnode-class");
    });

    jsPlumb.ready(jsPlumbMain);//【第一次进入】 初始化jsPlumb执行其下定义的jsPlumbMain方法

    // 放入拖动节点
    function dropNode (dataset, ui, obj) {
        //先清空和禁用设置按钮
        $(jnode_controlId).find(".clean").val("");
        $(jnode_controlId).find("button").removeClass("btn-info").addClass("btn-default").prop("disabled",true);//控制保存设置按钮
        //准备参数
        var dataObj = ui.position;
        //console.log("ui.position",position);
        var left = parseInt(ui.offset.left - $(obj).offset().left);
        var top = parseInt(ui.offset.top - $(obj).offset().top);
        dataObj.id = uuid.v1().replace(/-/g,"");
        node_num++;//顺序（次数）
        var jnodeType = dataset.jnodeType;
        var timestamp=new Date().getTime();//当前时间戳
        dataObj.jnodeCode = timestamp;// nodeCode_prefix+((node_num>9)?node_num:'0'+node_num);//格式如：F001+01
        if("start"==jnodeType){//结束节点可多个
            // if(("start"==jnodeType || "end"==jnodeType) ){
            dataObj.jnodeCode = jnodeType+"01";
            if(checkedNodeMap[jnodeType] && (checkedNodeMap[jnodeType]*1)>0) {
                layer.msg("【" + ui.helper.text() + "】节点已存在！");
                showConsole("新增节点[" + ui.helper.text() + "】已存在！",checkedNodeMap);
                return;
            }
        }
        //统计计算该节点类型个数 ++
        countNodeType(true,jnodeType);

        var jnodeName = ui.helper.text();
        dataObj.jnodeNum = node_num;
        dataObj.x = top;
        dataObj.y = left;//$('#diagramContainer-left').outerWidth();
        dataObj.jnodeType=jnodeType;//类型
        dataObj.jnodeClass=dataset.jnodeClass;
        dataObj.jnodeLast=dataset.jnodeLast;//上一步：审核不通过
        dataObj.jnodeNext=dataset.jnodeNext;//下一步：审核通过

        var jnodeTypNum = (checkedNodeMap[jnodeType]*1);
        if("judge"==jnodeType){
            jnodeName = "<i class='fa fa-plus-circle'></i><font class='hidden'>判断"+jnodeTypNum+"</font>";
        }else if("task"==jnodeType){
            jnodeName = ui.helper.text()+jnodeTypNum;
        }
        dataObj.jnodeName=jnodeName;
        dataObj.ruleId = "";//为空标识需要新增入库的节点
        // console.log("create drop jnode dataObj",dataObj);
        showConsole("create drop jnode dataObj",dataObj);
        var targetHtml = renderHtml(dataObj);
        $(jnode_areaId).append(targetHtml);//追加元素
        initSetNode(dataObj);// 初始化节点设置

        addNodeSubmitForm(dataObj);
    }
    
    function addNodeSubmitForm(dataObj) {
        var id = dataObj.id;
        $("#"+id).find(".jnode-box").click();
        var formId = "control_body_form1";
        var index_load = layer.load(1, {shade: false});
        showConsole("节点增加进行中","code="+dataObj.jnodeCode+",text="+dataObj.jnodeName+",id="+id);
        $.ajax({
            type:'post',url:common_submit_url,dataType:'json',data:$("#"+formId).serialize(),success: function(myData){
                console.log(formId+" save result",myData);
                showConsole("节点增加已完成","code="+dataObj.jnodeCode+",text="+dataObj.jnodeName+",id="+id+",result="+myData.msg);
                layer.close(index_load);
                if(myData.flag=="T"){
                    // layer.msg("新增节点成功！");
                    var ruleId = myData.ids.sysAuditRule_ruleId;
                    click_jnodeBoxObj.attr("rule-id",ruleId);
                    $(jnode_controlId).find("input[name='sysAuditRule.w_ruleId']").val(ruleId);
                }else{
                    layer.msg("操作失败！"+myData.msg);
                }
            },
            error: function (e) {
                layer.msg("操作失败！");
                layer.close(index_load);
            }
        });
    }

    //计算已选择各类型节点的个数
    function countNodeType(isAdd,nodeType) {
        var nodeTypeCount = 0;
        if(checkedNodeMap[nodeType]){
            nodeTypeCount = checkedNodeMap[nodeType]*1;
        }
        if(isAdd){
            nodeTypeCount++;
        }else{
            nodeTypeCount--;
        }
        checkedNodeMap[nodeType] = nodeTypeCount;
        // console.log(checkedNodeMap);
    }

    //移除选中节点时，同时移除原节点和目标节点内的"jnode-rule"属性关系
    function removeNodeRulesByThisNode(obj) {
        var currentUuid = obj.parent().attr("id");
        var jnodeRuleStr =  obj.attr("jnode-rule");
        // var endpointObj = jsPlumb.getEndpoints(currentUuid);//四周端点
        // console.log("endpointObj",endpointObj);
        var updateNodeArr = [];//记录需要更新nodeConfig的节点对象
        if (!strUtil.isNull(jnodeRuleStr)) {
            jnodeRuleStr = jnodeRuleStr.replace(/'/g, "\"");
            var nexts = JSON.parse(jnodeRuleStr).nexts;
            var lasts = JSON.parse(jnodeRuleStr).lasts;
            // console.log("this node lasts",lasts);
            if(lasts.length>0){
                for(var i=0; i<lasts.length; i++) {
                    var item = lasts[i];
                    var source_code = item.code;//来源节点编号
                    console.log("source node["+source_code+"] remove nexts id-->",currentUuid);
                    var source_jnodeBoxObj = $(jnode_areaId).find("div[jnode-code='"+source_code+"']");
                    if(source_jnodeBoxObj){//移除source原节点中关于此项uuid的next的配置项
                        var source_jnodeRuleStr = source_jnodeBoxObj.attr("jnode-rule");
                        if (!strUtil.isNull(source_jnodeRuleStr)) {
                            source_jnodeRuleStr = source_jnodeRuleStr.replace(/'/g, "\"");
                            var source_ruleJson = JSON.parse(source_jnodeRuleStr);
                            var source_nexts = source_ruleJson.nexts;
                            if(source_nexts.length>0){
                                //过滤掉数组内id等currentUuid的元素
                                source_nexts = jQuery.grep(source_nexts, function(itemObj) {
                                    return (itemObj.id != currentUuid);
                                });
                                source_ruleJson.nexts = source_nexts;
                                var source_ruleJsonStr = JSON.stringify(source_ruleJson);//nexts.join("|");
                                console.log("source node["+source_code+"] new ruleJsonStr-->",source_ruleJsonStr);
                                source_jnodeBoxObj.attr("jnode-rule",source_ruleJsonStr.replace(/\"/g,"'"));
                                updateNodeArr.push(source_jnodeBoxObj);
                            }
                        }
                    }
                }
            }

            if(nexts.length>0){
                for(var i=0; i<nexts.length; i++) {
                    var item = nexts[i];
                    // var last_uuid = item.id;
                    var target_code = item.code;//来源节点编号
                    console.log("target node["+target_code+"] remove nexts id-->",currentUuid);
                    var target_jnodeBoxObj = $(jnode_areaId).find("div[jnode-code='"+target_code+"']");
                    if(target_jnodeBoxObj){//移除target原节点中关于此项uuid的lasts的配置项
                        var target_jnodeRuleStr = target_jnodeBoxObj.attr("jnode-rule");
                        if (!strUtil.isNull(target_jnodeRuleStr)) {
                            target_jnodeRuleStr = target_jnodeRuleStr.replace(/'/g, "\"");
                            var target_ruleJson = JSON.parse(target_jnodeRuleStr);
                            var target_lasts = target_ruleJson.lasts;
                            if(target_lasts.length>0){
                                //过滤掉数组内id等currentUuid的元素
                                target_lasts = jQuery.grep(target_lasts, function(itemObj) {
                                    return (itemObj.id != currentUuid);
                                });
                                target_ruleJson.lasts = target_lasts;
                                var target_ruleJsonStr = JSON.stringify(target_ruleJson);//nexts.join("|");
                                console.log("target node["+target_code+"] new ruleJsonStr-->",target_ruleJsonStr);
                                target_jnodeBoxObj.attr("jnode-rule",target_ruleJsonStr.replace(/\"/g,"'"));
                                updateNodeArr.push(target_jnodeBoxObj);
                            }
                        }
                    }
                }
            }
        }
        console.log("updateNodeArr",updateNodeArr);
        return updateNodeArr;
    }

    //初始化节点设置
    function initSetNode (dataObj) {
        var id=dataObj.id;
        // jsPlumb.draggable(id, {containment: 'parent'})

        var isvisible = false;
        if("judge"==dataObj.jnodeType){
          isvisible = true;//只有【判断节点】显示线上的覆盖Label标签
        }
        //设置四周端点
        visioConfig.baseArchors.forEach(function (key) {
            console.log("addEndpoint on id",id);
          jsPlumb.addEndpoint(
              id,{
                  uuid: id+"-"+key,//给该端点加上一个uuid属性, 方便后续通过connect()方法，将两个断点链接上
                  anchors: key,
                  //连接器上的覆盖
                  connectorOverlays: [
                      ["Arrow", {width: 5, length: 5, location: 1, id: "arrow",visible: isvisible}],//连接器上配置的箭头
                      ["Label", {label: "表达式", id: "myLabel", cssClass: "connectorLabel",visible: isvisible, events:{//连接器上覆盖的label标签
                          "click":function (labelOverlay,originalEvent) {
                              var connection = labelOverlay.component;
                              // console.log("clicked on label to connect",connection);
                              //console.log("clicked on label for connection",labelOverlay.component.id+"=>"+labelOverlay.labelText);
                              clickConnectOverlay(connection);
                          }
                        }
                    }]
                  ]
              },visioConfig.hollowCircle);
        });

        //让节点元素可拖动
        // jsPlumb.draggable(id, {containment: 'parent'});//containment: 'parent'只能在固定区域内移动
        jsPlumb.draggable(id, {containment: 'parent',grid: [1, 1],opacity: 0.5});//containment: 'parent'只能在固定区域内移动

        //jsPlumb.addEndpoints(id, [{anchors: ['TopCenter', 'RightMiddle', 'BottomCenter', 'LeftMiddle']}], visioConfig.hollowCircle)
        //给节点元素绑定事件
        $("#"+id).on("contextmenu", ".jnode-box", function () {
                //鼠标右键点击时删除
                var nodeName = $(this).find("span").text();
                var nodeType = $(this).attr("jnode-type");
                var currentUuid = $(this).parent().attr("id");
                console.log("remove 节点",$(this)[0].getAttribute("jnode-code"));
                if (confirm("确认要删除节点【"+nodeName+"】吗？")) {
                    var index_load = layer.load(1, {shade: false});
                    console.log("remove this node uuid-->",currentUuid);
                    showConsole("删除节点进行中",currentUuid+" || "+nodeName);
                    var updateNodeObjArr = removeNodeRulesByThisNode($(this));//删除和此节点相关的其他节点关系

                    jsPlumb.removeAllEndpoints(currentUuid);//移除此id节点的四周所有端点
                    $(this).parent().remove();
                    node_num--;
                    click_jnodeBoxObj=null;
                    $(jnode_controlId).find(".clean").val("");
                    $(jnode_controlId).find("button").removeClass("btn-info").addClass("btn-default").prop("disabled",true);//控制保存设置按钮
                    var ruleId = $(this).attr("rule-id");
                    if(!strUtil.isNull(ruleId)){//非空时-删除数据库该节点
                        var postParamData = {};
                        postParamData["pageName"]="audit-rule-list";
                        postParamData["formName"]="delForm";
                        postParamData["sysAuditRule.w_ruleId"]=ruleId;
                        $.ajax({type:'post',url:common_submit_url,dataType:'json',data:postParamData,success: function(myData){
                            layer.close(index_load);
                            showConsole("删除节点已完成",currentUuid+" || "+nodeName+",result="+myData.msg);
                            console.log("node remove",myData);
                        }});

                        //批量更新相关联节点的nodeConfig关系
                        if(updateNodeObjArr.length>0){
                            updateNodeSourceTarget(updateNodeObjArr);
                        }
                    }
                    //统计计算该节点类型个数 --
                    countNodeType(false,nodeType);
                }
                return false;
            //}).on("click", ".fa-cog", function () {
                //鼠标点击设置元素时，删除
                //clickJnodeBoxControl($(this).parent().find(".jnode-box"),"node");
            //}).on("dblclick", ".jnode-box",function(){
            }).on("click", ".jnode-box",function(){
                //鼠标点击
                clickJnodeBoxControl($(this),"node");
            });

    }
    
    //节点点击加载数据，进行各个参数设置
    function clickJnodeBoxControl(obj,type) {
        // console.log("doubleClick obj",obj);
        var index_load_jnode = layer.load(1, {shade: false});
        $(jnode_controlId).find(".clean").val("");//清空文本框
        var jnodeMap = {};
        var ifStart = "F";
        var jnodeType = obj.attr("jnode-type");
        var jnodeName = obj.text();
        var jnodeCode = obj.attr("jnode-code");
        if (jnodeType == "start") {
            ifStart = "T";
        }
        //jnode-panel-active //选择边框 jnode-flicker //闪烁样式
        // obj.parent().addClass("jnode-panel-active").siblings().removeClass("jnode-panel-active");//当前节点选中，其他兄弟节点移除
        var ruleId = obj.attr("rule-id");
        var nextNode = obj.attr("jnode-next");
        if(jnodeType == "task"){
            $(jnode_controlId).find(".item-task").removeClass("hidden");
            $(jnode_controlId).find(".item-judge-line").addClass("hidden");
            $(jnode_controlId).find("input[jnode-name='jnodeName']").prop("readonly", false);
            $(jnode_controlId).find("button").removeClass("btn-default").addClass("btn-info").prop("disabled", false);//控制保存设置按钮
        }else if(jnodeType == "judge"){
            nextNode = "";
            jnodeName = obj.find("span > font").text();
            if(type=="line"){//点击以判断节点为source的相关线
                $(jnode_controlId).find(".item-judge-line").removeClass("hidden");
                $(jnode_controlId).find(".item-task").addClass("hidden");
            }else{
                $(jnode_controlId).find(".item-task").removeClass("hidden");
                $(jnode_controlId).find(".item-judge-line").addClass("hidden");
            }
            $(jnode_controlId).find("button").removeClass("btn-default").addClass("btn-info").prop("disabled", false);//控制保存设置按钮
        }else{
            //start,end 节点
            $(jnode_controlId).find(".item-judge-line").addClass("hidden");
            $(jnode_controlId).find(".item-task").addClass("hidden");
            $(jnode_controlId).find("input[jnode-name='jnodeName']").prop("readonly", true);
            $(jnode_controlId).find("button").removeClass("btn-default").addClass("btn-info").prop("disabled", true);//控制保存设置按钮
        }

        var currentUuid = obj.parent().attr("id");
        jnodeMap["x"] = parseInt(obj.offset().top - $(jnode_areaId).offset().top);
        jnodeMap["y"] = parseInt(obj.offset().left - $(jnode_areaId).offset().left);
        jnodeMap["id"] = currentUuid;
        jnodeMap["code"] = jnodeCode;
        jnodeMap["type"] = jnodeType;
        var jnodeRuleStr = obj.attr("jnode-rule");
        var nexts = [];
        var lasts = [];
        if (!strUtil.isNull(jnodeRuleStr)) {
            jnodeRuleStr = jnodeRuleStr.replace(/'/g, "\"");
            nexts = JSON.parse(jnodeRuleStr).nexts;
            lasts = JSON.parse(jnodeRuleStr).lasts;
        }
        jnodeMap["nexts"] = nexts;
        jnodeMap["lasts"] = lasts;
        jnodeMap["jnodeConfig"] = JSON.stringify(jnodeMap);// strUtil.mapToJsonStr(jnodeMap);

        jnodeMap["jnodeCode"] = jnodeCode;//obj.attr("jnode-code");//obj.parent().attr("id");
        jnodeMap["jnodeNum"] = obj.attr("jnode-num");
        jnodeMap["jnodeName"] = jnodeName;
        jnodeMap["jnodeType"] = jnodeType;
        jnodeMap["ifStart"] = ifStart;
        jnodeMap["jnodeLast"] = obj.attr("jnode-last");
        jnodeMap["jnodeNext"] = nextNode;
        jnodeMap["ruleId"] = ruleId;
        jnodeMap["jnodeRule"]="";
        if (!strUtil.isNull(ruleId)) {
            $(jnode_controlId).find("input[name='formName']").val("editForm");
        } else {
            $(jnode_controlId).find("input[name='formName']").val("addForm");
        }
        console.log("click jnode-box-jnode data->" + jnodeName, jnodeMap);
        showConsole("当前选中节点","code="+jnodeCode+",text="+jnodeName+",uuid="+currentUuid+",nexts=["+nexts.length+"],lasts=["+lasts.length+"]");

        //按照定义[jnode-name]属性赋值文本框
        $(jnode_controlId).find("[jnode-name]").each(function () {
            $(this).val(jnodeMap[$(this).attr("jnode-name")]);
        });
        $("#jnode-control-title-span").text("[" + jnodeName + "]");

        click_jnodeBoxObj = obj;
        if (!strUtil.isNull(ruleId)) {
            //加载审核规则其他对象属性
            var postParamData = {};
            postParamData["pageName"] = "audit-rule-list";
            postParamData["formName"] = "searchForm";
            postParamData["sysAuditRule.w_ruleId"] = ruleId;
            $.getJSON(common_info_url, postParamData, function (resultData) {
                layer.close(index_load_jnode);
                // layer.tips('['+jnodeName+']节点加载完成，可修改保存设置！', '#title_header', {tips: [3,'#00c0ef']});
                console.log("auditRule search data ", resultData);
                $(jnode_controlId).find("input[name='sysAuditRule.toUrl']").val(resultData.toUrl);
                $(jnode_controlId).find("input[name='sysAuditRule.checkUser']").val(resultData.checkUser);
                $(jnode_controlId).find("input[name='sysAuditRule.linkUrl']").val(resultData.linkUrl);
                $(jnode_controlId).find("input[name='sysAuditRule.tableName']").val(resultData.tableName);
                $(jnode_controlId).find("input[name='sysAuditRule.colName']").val(resultData.colName);
                $(jnode_controlId).find("input[name='sysAuditRule.pageName']").val(resultData.pageName);
                $(jnode_controlId).find("input[name='sysAuditRule.formName']").val(resultData.formName);
                $(jnode_controlId).find("input[name='sysAuditRule.colNameY']").val(resultData.colNameY);
                $(jnode_controlId).find("input[name='sysAuditRule.colNameN']").val(resultData.colNameN);
                $(jnode_controlId).find("input[name='sysAuditRule.ifCustom']").val(resultData.ifCustom);
            });
        } else {
            layer.close(index_load_jnode);
        }
    }

    //点击连接线上覆盖的Label标签
    function clickConnectOverlay(connection) {
        if(connection && connection.source){//判断是否有source
            var overlay = connection.getOverlay("myLabel");
            var overLayLabelText = overlay.getLabel();
            var uuid_source_startpoint = connection.endpoints[0].getUuid();
            var uuid_target_endpoint = connection.endpoints[1].getUuid();
            var source_relKey=uuid_source_startpoint+"->"+uuid_target_endpoint;

            var sourceObj = connection.source;
            var souObj = $(sourceObj.firstElementChild);
            var sourceJnodeType = souObj.attr("jnode-type");
            var source_jnodeRuleStr = souObj.attr("jnode-rule");
            var ruleName = overLayLabelText,ruleValue = "";
            if(!strUtil.isNull(source_jnodeRuleStr)){//非空时标识反显查找对应关系文本
                source_jnodeRuleStr = source_jnodeRuleStr.replace(/'/g,"\"");
                var source_ruleJson = JSON.parse(source_jnodeRuleStr);
                var source_nexts = source_ruleJson.nexts;
                for(var i=0; i<source_nexts.length; i++) {
                    var item = source_nexts[i];
                    var objsKey = item.source +"->"+ item.target;
                    if(source_relKey == objsKey) {
                        ruleValue = item.rule;
                        ruleName = item.name;
                        break;
                    }
                }
            }
            // if(sourceJnodeType=="judge"){//每条线都可以修改。
            click_connectionObj = connection;//记录当前点击对象
            clickJnodeBoxControl(souObj,"line");//触发点击事件，加载数据
            $("#jnode-control-title-span").text("[" + ruleName + "]");
            $(jnode_controlId).find("input[jnode-name='jnodeExprName']").val(ruleName);
            $(jnode_controlId).find("input[jnode-name='jnodeExprVal']").val(ruleValue);//
            // }
        }
    }

    //利用mustache模板工具，把数据对象dataObj渲染为html
    function renderHtml (dataObj) {
        return Mustache.render($(jnode_templateId).html(), dataObj);
        //return Mustache.render(visioConfig.visioTemplate[templateId], dataObj);
    }

    //连接线时，初始化两端节点的相关属性。
    function addConnectSourceTarget(connInfo){
        var sourceObj = connInfo.source;
        var sourceUuid = sourceObj.id;
        var targetObj = connInfo.target;
        var targetUuid = targetObj.id;
        var targetJnodeName = targetObj.innerText;
        // console.log("connection sourceObj",sourceObj);
        // console.log("connection targetObj",targetObj);
        var lastCode = sourceObj.firstElementChild.getAttribute("jnode-code");
        var sourceJnodeType = sourceObj.firstElementChild.getAttribute("jnode-type");
        var nextCode = targetObj.firstElementChild.getAttribute("jnode-code");
        var targetJnodeType = targetObj.firstElementChild.getAttribute("jnode-type");
        var ruleVal = "";
        sourceObj.firstElementChild.setAttribute("jnode-next",nextCode);
        targetObj.firstElementChild.setAttribute("jnode-last",lastCode);
        var uuid_source_startpoint = connInfo.connection.endpoints[0].getUuid();
        var uuid_target_endpoint = connInfo.connection.endpoints[1].getUuid();
        var source_relKey=uuid_source_startpoint+"->"+uuid_target_endpoint;
        if(sourceJnodeType=="judge"){//判断条件节点。
            ruleVal = "result==T";
        }else{
            ruleVal = "";
            // nextCode = "";
        }
        if(targetJnodeType=="judge"){
            targetJnodeName = $(targetObj.firstElementChild.innerHTML).find("font").text();
        }
        var source_isRelKeyExist = false,target_isRelKeyExist = false;//据此判断是新增画线还是反显历史数据
        var source_ruleJson = {},target_ruleJson = {};
        var source_nexts=[],source_lasts=[],target_nexts=[],target_lasts=[];

        //给目标source节点的jnode-rule属性内，新增nexts目标关系
        var labelText = "";
        var source_jnodeRuleStr = sourceObj.firstElementChild.getAttribute("jnode-rule");
        if(!strUtil.isNull(source_jnodeRuleStr)){//非空时标识反显查找对应关系文本
            source_jnodeRuleStr = source_jnodeRuleStr.replace(/'/g,"\"");
            source_ruleJson = JSON.parse(source_jnodeRuleStr);
            source_nexts = source_ruleJson.nexts;
            source_lasts = source_ruleJson.lasts;
            for(var i=0; i<source_nexts.length; i++) {
                var item = source_nexts[i];
                var objsKey = item.source +"->"+ item.target;
                // if(item.id == targetUuid) {
                if(source_relKey == objsKey) {
                    labelText = item.name+"-["+item.rule+"]";
                    source_isRelKeyExist = true;//同关系已存在
                    // layer.msg("此关系已存在了，请删除！");
                    break;
                }
            }
        }
        if(!source_isRelKeyExist){ //没有就新增（新画的线） //给sourceObj添加去往目标节点的关系rule
            labelText = "to "+targetJnodeName;
            var nextItem= {};
            nextItem.name = labelText;
            nextItem.rule = ruleVal;
            nextItem.code = nextCode;
            nextItem.id = targetUuid;
            nextItem.source = uuid_source_startpoint;
            nextItem.target = uuid_target_endpoint;
            source_nexts.push(nextItem); //新增元素
            source_ruleJson.nexts=source_nexts;
            source_ruleJson.lasts = source_lasts;
            var source_ruleJsonStr = JSON.stringify(source_ruleJson);//nexts.join("|");
            console.log("source node add nexts item["+nextCode+"] is ruleJsonStr-->",source_ruleJsonStr);
            showConsole("source node add nexts item["+nextCode+"] is ruleJsonStr-->",source_ruleJsonStr);
            sourceObj.firstElementChild.setAttribute("jnode-rule",source_ruleJsonStr.replace(/\"/g,"'"));
        }

        //给目标target节点的jnode-rule属性内，新增lasts来源关系
        var target_jnodeRuleStr = targetObj.firstElementChild.getAttribute("jnode-rule");
        if(!strUtil.isNull(target_jnodeRuleStr)){//非空时标识反显查找对应关系文本
            target_jnodeRuleStr = target_jnodeRuleStr.replace(/'/g,"\"");
            target_ruleJson = JSON.parse(target_jnodeRuleStr);
            target_nexts = target_ruleJson.nexts;
            target_lasts = target_ruleJson.lasts;
            for(var i=0; i<target_lasts.length; i++) {
                var item = target_lasts[i];
                if(item.id == sourceUuid) {
                    target_isRelKeyExist = true;//同关系已存在
                    break;
                }
            }
        }
        if(!target_isRelKeyExist){ //没有就新增（新画的线） //给targetObj添加来自源节点的关系last
            var lastItem = {};
            lastItem.code = lastCode;
            lastItem.id = sourceUuid;
            target_lasts.push(lastItem); //新增元素
            target_ruleJson.nexts=target_nexts;
            target_ruleJson.lasts =target_lasts;
            var target_ruleJsonStr = JSON.stringify(target_ruleJson);
            console.log("target node add lasts item["+nextCode+"] is ruleJsonStr-->",target_ruleJsonStr);
            showConsole("target node add lasts item["+nextCode+"] is ruleJsonStr-->",target_ruleJsonStr);
            targetObj.firstElementChild.setAttribute("jnode-rule",target_ruleJsonStr.replace(/\"/g,"'"));

        }
        //修改连接线的覆盖文本
        connInfo.connection.getOverlay("myLabel").setLabel(labelText);
    }

    //批量修改指定节点对象的sysAuditRule.nodeConfig字段，重新update入库
    function updateNodeSourceTarget(objArray) {
        if(objArray && objArray.length>0){
            var wRuleIdArr = [],nodeConfigArr = [],nodeCodeArr=[];
            $.each(objArray,function(index,obj){
                var nodeCode = obj.attr("jnode-code");//编号
                var nodeObj = getUpdateJnodeObj(obj);//目标节点对象数据
                var ruleId = nodeObj.ruleId;
                var nodeConfigStr = JSON.stringify(nodeObj.nodeConfig);
                console.log(ruleId+"-node new",nodeObj);
                nodeCodeArr.push(nodeCode);
                wRuleIdArr.push(ruleId);
                nodeConfigArr.push(nodeConfigStr);
            });
            console.log("nodeConfigArr",nodeConfigArr);
            console.log("wRuleIdArr",wRuleIdArr);
            var postParamData = {};
            postParamData["pageName"] = "audit-rule-list";
            postParamData["formName"] = "editFormBatch";
            postParamData["ifBatch"] = "T";
            postParamData["sysAuditRule.splitAttr"] = "nodeConfig";
            postParamData["sysAuditRule.nodeConfig"] = nodeConfigArr.join('-#-');//source_nodeConfigStr+"-#-"+target_nodeConfigStr;
            postParamData["sysAuditRule.w_ruleId"] = wRuleIdArr.join('-#-');
            var index_load = layer.load(1, {shade: false});
            showConsole("节点连线配置更新进行中：","codes=["+nodeCodeArr.length+"]{"+nodeCodeArr.join(',')+"}");
            $.ajax({type:'post',url:common_submit_url,dataType:'json',data:postParamData,success: function(myData){
                showConsole("节点连线配置更新已完成：","codes=["+nodeCodeArr.length+"]{"+nodeCodeArr.join(',')+"},result="+myData.msg);
                layer.close(index_load);
            }});
        }
    }
    //获取jnodeBoxObj操作对象，以备更新
    function getUpdateJnodeObj(obj) {
        var nodeObj = {};
        nodeObj.ruleId=obj.attr("rule-id");
        var currentUuid = obj.parent().attr("id");
        var nodeConfig = {};
        // nodeConfig.x=parseInt(obj.offsetTop+4);
        // nodeConfig.y=parseInt(obj.offsetLeft+3);
        nodeConfig.x = parseInt(obj.offset().top - $(jnode_areaId).offset().top);
        nodeConfig.y = parseInt(obj.offset().left - $(jnode_areaId).offset().left);
        nodeConfig.id = currentUuid;
        nodeConfig.code = obj.attr("jnode-code");
        nodeConfig.type = obj.attr("jnode-type");
        var jnodeRuleStr = obj.attr("jnode-rule");
        var nexts=[],lasts=[];
        if(!strUtil.isNull(jnodeRuleStr)){
            jnodeRuleStr = jnodeRuleStr.replace(/'/g,"\"");
            var target_ruleJson = JSON.parse(jnodeRuleStr);
            nexts = target_ruleJson.nexts;
            lasts = target_ruleJson.lasts;
        }
        nodeConfig.nexts=nexts;
        nodeConfig.lasts=lasts;
        nodeObj.nodeConfig=nodeConfig;
        return nodeObj;
    }

    //移除连线时，同时移除原节点和目标节点内的"jnode-rule"属性关系
    function removeNodeRulesByConnect(sourceObj,targetObj,relKey) {
        if(strUtil.isNull(relKey)){
           return;
        }
        var source_jnodeRuleStr = sourceObj.firstElementChild.getAttribute("jnode-rule");
        var target_jnodeRuleStr = targetObj.firstElementChild.getAttribute("jnode-rule");
        var sourceUuid = sourceObj.id;
        var targetUuid = targetObj.id;
        //移除源节点的netxs关系
        if(!strUtil.isNull(source_jnodeRuleStr)){
            source_jnodeRuleStr = source_jnodeRuleStr.replace(/'/g,"\"");
            var source_ruleJson = JSON.parse(source_jnodeRuleStr);
            var source_nexts = source_ruleJson.nexts;
            if(source_nexts.length>0){
                //过滤掉数组内id等currentUuid的元素
                source_nexts = jQuery.grep(source_nexts, function(itemObj) {
                    var objsKey = itemObj.source +"->"+ itemObj.target;
                    return (objsKey != relKey);
                });
                source_ruleJson.nexts = source_nexts;
                var source_ruleJsonStr = JSON.stringify(source_ruleJson);
                console.log("source update ruleJsonStr-->",source_ruleJsonStr);
                sourceObj.firstElementChild.setAttribute("jnode-rule",source_ruleJsonStr.replace(/\"/g,"'"));
            }
        }
        //移除目标节点的lasts关系
        if(!strUtil.isNull(target_jnodeRuleStr)){
            target_jnodeRuleStr = target_jnodeRuleStr.replace(/'/g,"\"");
            var target_ruleJson = JSON.parse(target_jnodeRuleStr);
            var target_lasts = target_ruleJson.lasts;
            if(target_lasts.length>0){
                //过滤掉数组内id等currentUuid的元素
                target_lasts = jQuery.grep(target_lasts, function(itemObj) {
                    return (itemObj.id != sourceUuid);
                });
                target_ruleJson.lasts = target_lasts;
                var target_ruleJsonStr = JSON.stringify(target_ruleJson);
                console.log("target update ruleJsonStr-->",target_ruleJsonStr);
                targetObj.firstElementChild.setAttribute("jnode-rule",target_ruleJsonStr.replace(/\"/g,"'"));
            }
        }

    }

    // jsPlumbMain 主要入口
    function jsPlumbMain () {
        jsPlumb.setContainer(areaId);

        //绑定连接线点击事件
        /**
        jsPlumb.bind('click', function (connection, originalEvent) {
            $(jnode_areaId).find(".jnode-panel").removeClass("jnode-active");//当前节点选中，其他兄弟节点移除
        });
         **/
        //绑定鼠标右击连线事件
        jsPlumb.bind('contextmenu',function (connection, originalEvent) {
            // console.log("connection remove",connection);
            // connection.hideOverlay("myLabel");//隐藏指定线的label
            if(connection.source && connection.target){//判断是否连接线
                var labelText = connection.getOverlay("myLabel").getLabel();
                // console.log("remove 连线",connection.source.firstElementChild.getAttribute("jnode-code"));
                // console.log("remove 连线",$(connection.source.firstElementChild).attr("jnode-code"));
                if (confirm("确认要删除连线【"+labelText+"】吗？")) {
                    //删除两端的源节点和目标节点所定义的属性。
                    var sourceObj = connection.source;
                    var targetObj = connection.target;
                    sourceObj.firstElementChild.setAttribute("jnode-next","");
                    targetObj.firstElementChild.setAttribute("jnode-last","");
                    //删除连接线rel关系内容
                    var uuid_source_startpoint = connection.endpoints[0].getUuid();
                    var uuid_target_endpoint = connection.endpoints[1].getUuid();
                    var relKey=uuid_source_startpoint+"->"+uuid_target_endpoint;
                    showConsole("删除连线进行中",labelText+" || "+relKey);
                    console.log("remove connection-->",labelText+" || "+relKey);
                    removeNodeRulesByConnect(sourceObj,targetObj,relKey);//删除源节点和目标节点中和此连线相关的关系rule
                    //更新数据库关系
                    updateNodeSourceTarget([$(sourceObj.firstElementChild),$(targetObj.firstElementChild)]);
                    //删除线及两端锚点
                    jsPlumb.detach(connection);
                }
            }
            return false;
        });

        //绑定连接线连接时事件
        jsPlumb.bind("connection", function (connInfo, originalEvent) {
             // console.log("connection connInfo" ,connInfo);
            //console.log("connection originalEvent" ,originalEvent);
            if (connInfo.connection.sourceId == connInfo.connection.targetId) {
                jsPlumb.detach(connInfo);
                layer.msg("不能连接自己！");
            }else{
                addConnectSourceTarget(connInfo);
            }

        });
          /**
        jsPlumb.bind("beforeDrop", function (info) {
            console.log("beforeDrop 0",info.connection.endpoints[0].getUuid());
            //console.log("beforeDrop 1",info.connection.endpoints[1].getUuid());
        });
           //取消连接
           jsPlumb.bind("connectionDetached", function (conn, originalEvent) {
            if (conn.sourceId == conn.targetId) {
                //自己连接自己时会自动取消连接
            }else{
                    alert("删除连接从" + conn.sourceId + "到" + conn.targetId + "！");
            }
        });
           //将一条已存在的线条拖动走时的事件
        jsPlumb.bind("connectionMoved", function (params) {
            console.log("connectionMoved ",params);
        });
           **/
          //新拖动一条线的事件开始
        // jsPlumb.bind("connectionDrag", function (connection) {
        //     console.log("connectionDrag", connection);
        //     // console.log("connection " + connection.id + " is being dragged. suspendedElement is ", connection.suspendedElement, " of type ", connection.suspendedElementType);
        //     // addConnectSourceTarget(connection,"add");
        // });
        //新拖动一条线的事件开始停止
        jsPlumb.bind("connectionDragStop", function (connection) {
            // console.log("connectionDragStop",connection);
            var sourceObj = connection.source;
            var targetObj = connection.target;
            if(sourceObj && targetObj){
                updateNodeSourceTarget([$(sourceObj.firstElementChild),$(targetObj.firstElementChild)]);
            }
        });


        //定义可拖拽控件
        $('.jnode-box').draggable({
          helper: 'clone',
          scope: 'ss'
        });
        //定义可拖拽释放
        $(jnode_areaId).droppable({
          scope: 'ss',
          drop: function (event, ui) {
            //创建新节点
            dropNode(ui.draggable[0].dataset, ui,$(this));
          }
        });
          //启动初始化数据，反显
        $("#btn-init-jvisio").on("click",function () {
            initSearchAuditRuleJnodeData();
            showConsole("数据加载","已完成！");
        });

        initSearchAuditRuleJnodeData();//加载历史数据【第一次进入】
    }

    //初始化节点数据，进行修改
    function initSearchAuditRuleJnodeData() {
        node_num=0;
        click_jnodeBoxObj=null;
        $(jnode_controlId).find(".clean").val("");
        $(jnode_areaId).html("<div>Design Area</div>");

        var jnodeDataArray = [];//节点模拟数据
        var connectDataMap = {};//连接线模拟数据
        var req_url = common_list_url;
        if(!enable_connect_server){
            req_url = ctx+"/common/plateform/plugins/jvisio/test-data.js";
        }
        var index_load =  layer.load(1, {shade: false});//layer.msg("正在初始化");
        $.getJSON(req_url,
            $("#searchForm_ruledata").serialize(),
            function(resultData){
            console.log("initSearchAuditRuleJnodeData",resultData);
            if(resultData.flag=="T"){
                //1、初始化节点
                jnodeDataArray = resultData.rows;
                node_num +=resultData.total;
                console.log("rows-",JSON.stringify(resultData.rows));
                $.each(jnodeDataArray,function(index,item){
                    console.log("item-"+index,item);
                    var dataObj = {};
                    var nodeType = item.nodeType;
                    //统计计算该节点类型个数 --
                    countNodeType(true,nodeType);

                    var nodeConfigVal = item.nodeConfig;
                    if(!strUtil.isNull(nodeConfigVal)) {//新数据
                        dataObj = JSON.parse(nodeConfigVal);
                        var ruleJson ={};
                        ruleJson.nexts=dataObj.nexts;
                        ruleJson.lasts=dataObj.lasts;
                        dataObj.x=dataObj.x-4;
                        dataObj.y=dataObj.y-3;
                        var rulesJsonStr = JSON.stringify(ruleJson);//nexts.join("|");
                        dataObj.jnodeRule = rulesJsonStr.replace(/\"/g,"'");
                        // console.log("item-"+index,dataObj);
                    }else{
                        if(item.ifStart=="T"){
                            nodeType = "start";
                        }else if(item.next=="00"){
                            nodeType = "end";
                        }else{
                            nodeType = "task";
                        }
                        dataObj.id = uuid.v1();//.replace(/-/g,"");
                        dataObj.code = item.taskNo;
                        dataObj.x =  Math.floor(Math.random()*400);//随机数
                        dataObj.y = Math.floor(Math.random()*600);//随机数
                        dataObj.jnodeRule="";
                        dataObj.type = nodeType;
                        // dataObj.sourid = item;
                    }
                    var nodeNameText =strUtil.subStr2(((item.taskName.indexOf("]-")>-1)?item.taskName.split("]-")[1]:item.taskName),12);//dataObj.top+" x "+dataObj.left;
                    var taskNo = item.taskNo;
                    if(taskNo.length>2){
                        nodeNameText =nodeNameText;//+"-"+taskNo.substring(taskNo.length-2,taskNo.length);
                    }
                    dataObj.ruleId = item.ruleId;//记录业务数据主键id
                    dataObj.jnodeCode = item.taskNo;
                    dataObj.jnodeNum = item.num;
                    dataObj.jnodeName = nodeNameText;
                    dataObj.ifStart = item.ifStart;
                    dataObj.jnodeType = nodeType;//类型
                    dataObj.jnodeClass = jnodeClassMap[nodeType];
                    dataObj.jnodeLast=item.last;
                    dataObj.jnodeNext=item.next;
                    if("judge"==nodeType){
                        var jnodeTypNum = (checkedNodeMap[nodeType]*1);
                        dataObj.jnodeName = "<i class='fa fa-plus-circle'></i><font class='hidden'>"+nodeNameText+"</font>";
                    }
                    // console.log("create init jnode dataObj",dataObj);
                    var targetHtml = renderHtml(dataObj);
                    $(jnode_areaId).append(targetHtml);//追加元素
                    initSetNode(dataObj);// 初始化节点设置

                    if(!strUtil.isNull(dataObj.nexts) && dataObj.nexts.length>0){//新数据
                        for (var i = 0; i <dataObj.nexts.length; i++){
                            var key = dataObj.nexts[i].source+"->"+dataObj.nexts[i].target;
                            connectDataMap[key]=dataObj.nexts[i];
                        }
                    }
                });
                //2、初始化连线
                // console.log("create init jnode connectDataMap",connectDataMap);
                if(Object.keys(connectDataMap).length>0){
                    for(var k in connectDataMap) {
                        var conObj = connectDataMap[k];
                        var uuid_source_endpoint =conObj.source;
                        var uuid_target_endpoint =conObj.target;
                        // console.log(connectDataMap);
                        jsPlumb.connect({uuids:[uuid_source_endpoint, uuid_target_endpoint]});
                    }
                }
            }
            layer.close(index_load);

        });
    }

    //2、全部[jnode-name]清空
    function cleanContainerControl() {
        $(jnode_controlId).find("input[jnode-name]").val("");
        $(jnode_controlId).find(".clean").val("");
    }
    //初始化清空设置输入框
    cleanContainerControl();

    //监控台显示操作日志
    function showConsole(title,obj) {
        if(enable_console){
            $(".diagramContainer-console").find(".console-msg").html(title+" --> "+JSON.stringify(obj));
        }
    }

    //绑定事件-删除全部内容事件
    $("#btn-clean-jvisio").on("click",function () {
        var index_submit = layer.confirm('您确认删除右侧已设计的全部节点吗？', {btn: ['Yes','No'],closeBtn: 0,offset: '220px'}
            , function(){
                layer.close(index_submit);
                var index_load = layer.load(1, {shade: false});
                var postParamData = {};
                postParamData["pageName"]="audit-rule-list";
                postParamData["formName"]="delForm";
                postParamData["sysAuditRule.w_auditType"]=flowNo;
                $.ajax({type:'post',url:common_submit_url,dataType:'json',data:postParamData,success: function(myData){
                    layer.close(index_load);
                    showConsole("删除全部节点已完成","flowNo="+flowNo+",result="+myData.msg);
                    node_num = 0;
                    checkedNodeMap = {};
                    cleanContainerControl();
                    $(jnode_controlId).find("button").removeClass("btn-info").addClass("btn-default").prop("disabled",true);//控制保存设置按钮
                    initSearchAuditRuleJnodeData();//重新反显加载数据
                }});
            });
    });
    //绑定事件-保存设置按钮
    $(jnode_controlId).on("click","button[btn-save-control]", function () {
        var formId = $(this).attr("btn-save-control");
        //校验节点编号是否重复：
        var taskNoVal= $("#control_body_form1").find("input[name='sysAuditRule.taskNo']").val();
        var taskNoLeng = $(jnode_areaId).find("div[jnode-code='"+taskNoVal+"']").length;
        if(taskNoLeng>1){
            layer.msg("该节点编号【"+taskNoVal+"】有重复，请检查后重新设计！");
            return;
        }
        // alert(formId);
        var nodeType = $("#control_body_form1").find("select[name='sysAuditRule.nodeType']").val();
        var nodeName_New = $("#control_body_form1").find("input[jnode-name='jnodeName']").val();
        if(click_jnodeBoxObj==null||strUtil.isNull(nodeName_New)){
            layer.msg("无可操作对象！");
            return;
        }
        if(nodeType!="judge"){//判断条件节点。
            click_jnodeBoxObj.find("span").text(nodeName_New);//更改节点文字提示
        }
        if(formId=="control_body_form1"){
            //修改节点名称后，重新拼装配置参数
            var nodeConfigVal = $("#"+formId).find("input[name='sysAuditRule.nodeConfig']").val();
            var jnodeExprName = $("#"+formId).find("input[name='sysAuditRule.jnodeExprName']").val();
            var jnodeExprVal = $("#"+formId).find("input[name='sysAuditRule.jnodeExprVal']").val();
            if(nodeType=="judge" && !strUtil.isNull(nodeConfigVal) && !strUtil.isNull(jnodeExprVal) && click_connectionObj!=null){
                var uuid_source_startpoint = click_connectionObj.endpoints[0].getUuid();
                var uuid_target_endpoint = click_connectionObj.endpoints[1].getUuid();
                var thisRelKey=uuid_source_startpoint+"->"+uuid_target_endpoint;
                var dataObj = jQuery.parseJSON(nodeConfigVal);
                var nexts = dataObj.nexts;
                if(nexts.length>0){
                    for(var i=0; i<nexts.length; i++) {
                        var nextItem = nexts[i];
                        var objsKey = nextItem.source +"->"+ nextItem.target;
                        if(objsKey == thisRelKey) {
                            nextItem.name = jnodeExprName;
                            nextItem.rule = jnodeExprVal;
                            var newLabelText = jnodeExprName+'-['+jnodeExprVal+']';
                            click_connectionObj.getOverlay("myLabel").setLabel(newLabelText);//修改覆盖物文本
                            break;
                        }
                    }
                }
                dataObj.nexts = nexts;
                var source_ruleJsonStr = JSON.stringify(dataObj);
                click_jnodeBoxObj.attr("jnode-rule",source_ruleJsonStr.replace(/\"/g,"'"));
                console.log(formId+" save new nodeConfig-dataObj",dataObj);
                $("#"+formId).find("input[name='sysAuditRule.nodeConfig']").val(JSON.stringify(dataObj));
            }
            var lastVal = $("#"+formId).find("input[name='sysAuditRule.last']").val();
            var nextVal = $("#"+formId).find("input[name='sysAuditRule.next']").val();
//        if(strUtil.isNull(lastVal)){
//            layer.msg("["+nodeName_New+"]节点还未设置上一节点！");
//            return;
//        }
//        if(strUtil.isNull(nextVal)){
//            layer.msg("["+nodeName_New+"]节点还未设置下一节点，若无可重新拖拽[结束节点]！");
//            return;
//        }

        }
        var ruleId = $("#"+formId).find("input[jnode-name='ruleId']").val();
        var tis_msg = "";
        if(!strUtil.isNull(ruleId)){
            tis_msg = "修改";
            $("#"+formId).find("input[name='formName']").val("editForm");
        }else{
            tis_msg = "新增";
            $("#"+formId).find("input[name='formName']").val("addForm");
        }


        var index_submit = layer.confirm('您确定要'+tis_msg+'节点['+nodeName_New+']吗？', {btn: ['Yes','No'],closeBtn: 0,offset: '220px'}
            , function(){
                layer.close(index_submit);
                var index_load = layer.load(1, {shade: false});
                $.ajax({
                    type:'post',url:common_submit_url,dataType:'json',data:$("#"+formId).serialize(),success: function(myData){
                        console.log(formId+" save result",myData);
                        layer.msg("操作成功！");
                        layer.close(index_load);
                        if(myData.flag=="T"){
                            click_jnodeBoxObj.attr("rule-id",myData.ids.sysAuditRule_ruleId);
                        }
                    },
                    error: function (e) {
                        layer.msg("操作失败！");
                        layer.close(index_load);
                    }
                });
            });
    });



})()
